[[container-thread-naming]]
= Container Thread Naming
:page-section-summary-toc: 1

A `TaskExecutor` is used to invoke the consumer and the listener.
You can provide a custom executor by setting the `consumerExecutor` property of the container's `ContainerProperties`.
When using pooled executors, be sure that enough threads are available to handle the concurrency across all the containers in which they are used.
When using the `ConcurrentMessageListenerContainer`, a thread from the executor is used for each consumer (`concurrency`).

If you do not provide a consumer executor, a `SimpleAsyncTaskExecutor` is used for each container.
This executor creates threads with names similar to `<beanName>-C-<n>`.
For the `ConcurrentMessageListenerContainer`, the `<beanName>` part of the thread name becomes `<beanName>-m`, where `m` represents the consumer instance.
`n` increments each time the container is started.
So, with a bean name of `container`, threads in this container will be named `container-0-C-1`, `container-1-C-1` etc., after the container is started the first time; `container-0-C-2`, `container-1-C-2` etc., after a stop and subsequent start.

Starting with version `3.0.1`, you can now change the name of the thread, regardless of which executor is used.
Set the `AbstractMessageListenerContainer.changeConsumerThreadName` property to `true` and the `AbstractMessageListenerContainer.threadNameSupplier` will be invoked to obtain the thread name.
This is a `Function<MessageListenerContainer, String>`, with the default implementation returning `container.getListenerId()`.

